package universe.utils;

import java.util.ArrayList;
import java.util.List;

public class OcTree<T> {

	private final int SUBDIVISIONS = 8;
	private final int DIMENTION = 3;
	// public final int MAX_OCTREE_DEPTH = 6;
	public final int MIN_ELEM_PER_OCTREE = 3;
	public final int MAX_ELEM_PER_OCTREE = 6;
	public final int MAX_ELEM_PER_BUCKET = 4;

	private Node root;

	public OcTree(Vector3D v) {
		if (v.dimention() != DIMENTION) {
			throw new IllegalArgumentException("Vector dimention must be "
					+ DIMENTION);
		}
		root = new InternalNode(v);
	}

	public void add(Vector3D v, T elem) {
		if (v.dimention() != DIMENTION) {
			throw new IllegalArgumentException("Vector dimention must be "
					+ DIMENTION);
		}
		root = add(root, v, elem);
	}

	private Node add(Node node, Vector3D v, T elem) {

		return null;
	}

	private Vector3D getAvg(LeafNode node) {
		// TODO hacer
		return null;
	}

	private int getQuadrantNumber(InternalNode node, Vector3D v) {
		// TODO: hacer!
		return 0;
	}

	private class InternalNode extends Node {
		Vector3D v;
		Node nodes[];

		@SuppressWarnings("unchecked")
		public InternalNode(Vector3D v) {
			this.v = v;
			nodes = new OcTree.Node[SUBDIVISIONS];
			for (int i = 0; i < SUBDIVISIONS; i++) {
				nodes[i] = new LeafNode();
			}
		}
	}

	private class LeafNode extends Node {

		List<T> bucket;

		public LeafNode() {
			bucket = new ArrayList<T>(MAX_ELEM_PER_BUCKET + 1);
		}

		public boolean isFull() {
			return bucket.size() > MAX_ELEM_PER_BUCKET;
		}

	}

	private abstract class Node {
	}
}
